Micronautフレームワークを使ってみよう
What is Micronaut?
Micronaut(まいくろのーと)とは、JVMベースのフルスタックフレームワークです。
2018年5月にOSSとして公開され、先日最新バージョンの1.1がリリースされました。
Java/Groovy/Kotlinで実装することができ、テストしやすくコンテナ化も容易、
クラウドネイティブなアプリも簡単に構築できるようです。
Features of Micronaut
Micronautの主な特徴について、ここで説明している内容から抜粋して紹介します。
Fast start up & low memory consumption
リフレクションベースのIoCフレームワークだと、
すべてのフィールドやメソッドのリフレクションデータをロードしてキャッシュしますが、
Micronautではアプリケーションのコードベースのサイズに左右されないので、
起動が速く、メモリ消費も少なくすることができます。
Micronaut usging Graal VM
Micronautは、リフレクションを使用しないDIとAOPランタイムを持っているので、
アプリをGraalVM上で実行することが容易です。
GraalVMを使用すれば、わずか数十ミリ秒でMicronautアプリが起動します。
* GraalVM : Oracleの汎用VM.Javaアプリをネイティブのマシンコードにコンパイルする機能を持つ
fast & easy Testing
Unitテストでサーバを簡単に起動し、すぐに実行可能です。
import io.micronaut.runtime.server.EmbeddedServer import spock.lang.* class HelloClientSpec extends Specification { @Shared @AutoCleanup EmbeddedServer embeddedServer = ApplicationContext.run(EmbeddedServer) @Shared HelloClient client = embeddedServer .applicationContext .getBean(HelloClient) void "test hello world response"() { expect: client.hello().blockingGet() == "Hello World" } }
compile time DI & AOP
Micronautではリフレクションを使わずにコンパイル時のAOPを提供しています。
だからGraalVMとかでも簡単に動かせるんですね。
@Scheduled(fixedRate = "5m") @Retry(attempts='5') void everyFiveMinutes() { messageService.sendMessage("Hello World"); }
Build Reactive application
Micronautは、Reactive Streamを実装するフレームワーク(RxJavaとか)をサポートします。
@Client( id = "person-service" ) public interface PersonClient { public io.reactivex.Single<Person> save(@Body Single<Person>person) }
Micronaut Profiles
Micronautにはデフォルトで複数のプロファイルが組み込まれています。
プロファイルを使うことでアプリの雛形を生成したり、
対象プロファイル用のコマンドを使用することができます。
これは、後述するcreate-appコマンド(Micronautアプリを生成するコマンド)を使った場合、
コントローラ(create-controller)、クライアント(create-client)を
生成するためのコマンドが使えるようになったりします。
Clound Native
MicronautではGoogle Cloud Platform(GCP)やAmazon Web Services(AWS)を
統合したモジュールを提供しています。
これらを用いることにより、各種クラウドプラットフォームに対応したMicronautアプリを作成できます。
参考: Micronaut GCP Micronaut AWS
また、Micronaut AWSを使うと、AWS Lambdaを使ったMicronautアプリを作成することができます。
(Alexa SkillsとかAWS API Gatewayもサポート)
message driven
RabbitMQを統合したMicronaut RabbitMQモジュールを使えば、
Micronautアプリでメッセージ駆動型サービスが作成可能になります。
また、RabbitMQプロファイルを使用すれば、
producerとlistenerを作成する固有コマンドを使うことができます。
% mn create-app sample-mq-service --profile rabbitmq % mn create-rabbitmq-producer Message # make producer % mn create-rabbitmq-listener Message # make listener
develop serverless application
さきほどMicronaut AWSモジュールでLambdaアプリが開発できるといいました。
Micronautの、コンパイルタイムDI&AOPであればサーバーレス用関数を書くのに適しています。
@Field @Inject HelloService helloService Message hello(Person person) { helloService.hello(person) }
resilient microService
分散環境における障害対策であるとサーキットブレーカーなどの機能がデフォルトで組み込まれています、
import io.micronaut.retry.annotation.* @CircuitBreaker(reset = "30s") public List findBooks() { ... .. }
環境
今回使用した動作環境は以下のとおりです。
- OS : MacOS X 10.12.6
- Java : 1.8.0_212
Setup Micronaut
ではMicronautをインストールしてみましょう。
sdkmanを使うと簡単にセットアップできるので、まずはsdkmanをインストールします。
% curl -s "https://get.sdkman.io" | bash % sdk version SDKMAN 5.7.3+337
次に、micronautをインストールします。
% sdk install micronaut ==== BROADCAST ================================================================= * 2019-07-13: Groovy 3.0.0-beta-2 released on SDKMAN! #groovylang * 2019-07-11: Grails 4.0.0 released on SDKMAN! #grailsfw * 2019-07-10: Gradle 5.5.1 released on SDKMAN! #gradle ================================================================================ Downloading: micronaut 1.1.4 In progress... ######################################################################## 100.0% Installing: micronaut 1.1.4 Done installing! Setting micronaut 1.1.4 as default.
mnコマンドが使えるようになっていればMicronautのインストールは完了です。
% mn --version Resolving dependencies.. | Micronaut Version: 1.1.4 | JVM Version: 1.8.0_212
Hello Micronaut
Micronautアプリを作成してみましょう。
mn create-appコマンドを使えばシンプルなプロジェクトを生成できます。
% mn create-app example.micronaut.complete | Generating Java project... | Application created at /path/your/micronaut/complete
生成したプロジェクトはgradleをつかったプロジェクトとなっています。
IDEA等のIDEを使えば、そのまま開いて編集することが可能です。
最初にシンプルなControllerを作成します。
このControllerは/hello宛のGETリクエストを受けると文字列を返します。
// path/your/prject/complete/src/main/java/example/micronaut/HelloController.java package example.micronaut; import io.micronaut.http.MediaType; import io.micronaut.http.annotation.Controller; import io.micronaut.http.annotation.Get; import io.micronaut.http.annotation.Produces; @Controller("/hello") public class HelloController { @Get("/") @Produces(MediaType.TEXT_PLAIN) public String index() { return "Hello World"; } }
Controllerに対するテストも作成してみましょう。
@MicronautTestを使えばテストも簡単に作成可能です。
// path/your/prject/complete/src/test/java/example/micronaut/HelloControllerTest.java package example.micronaut; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import io.micronaut.http.HttpRequest; import io.micronaut.http.client.RxHttpClient; import io.micronaut.http.client.annotation.Client; import io.micronaut.test.annotation.MicronautTest; import org.junit.jupiter.api.Test; import javax.inject.Inject; @MicronautTest public class HelloControllerTest { @Inject @Client("/") RxHttpClient client; @Test public void testHello() { HttpRequest<String> request = HttpRequest.GET("/hello"); String body = client.toBlocking().retrieve(request); assertNotNull(body); assertEquals("Hello World", body); } }
gradleでtestを実行してみます。
% ./gradlew test Starting a Gradle Daemon, 1 incompatible Daemon could not be reused, use --status for details > Task :test BUILD SUCCESSFUL in 39s 4 actionable tasks: 2 executed, 2 up-to-date
runコマンドで起動してみましょう。
% ./gradlew run > Task :run Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8 17:12:14.213 [main] INFO io.micronaut.runtime.Micronaut - Startup completed in 6380ms. Server Running: http://localhost:8080 > :run
Controllerにcurlでアクセスしてみます。
%curl http://localhost:8080/hello Hello World
まとめ
今回はJVMベースのフルスタックフレームワーク、Micronautを少しだけ使ってみました。
機能説明でいったとおり、MicronautではCloud用モジュールが用意されていたり
GraalVMで動かしたりも可能なので、いろいろと試して見ようかと思います。
参考サイト
infoq : https://www.infoq.com/jp/news/2019/07/micronaut-1.1-cloud-native
Micronaut公式 : https://micronaut.io/